package ochart.elements.labels
{
	import caurina.transitions.Tweener;
	
	import ochart.chartClasses.IData;
	import ochart.core.ChartObject;
	import ochart.elements.DataElement;
	import ochart.utils.ArrayUtil;
	import ochart.utils.StringUtil;
	
	public class DataTip extends LabelBase implements IData
	{
		public static const CLASS_NAME:String = "DataTip"
		
		override public function get className():String
		{
			return CLASS_NAME;
		}
		
		public static const ALIAS:String = "dataTip";
		
		override public function get alias():String
		{
			return ALIAS;
		}
		
		public static const CODE_VALUE:String = "#value#";
		
		public static const CLOSEST:String = "closest";
		public static const HOVER:String = "hover";
		
		private var _isTargetsArrayChange:Boolean = false;

		public function get isTargetsArrayChange():Boolean
		{
			return _isTargetsArrayChange;
		}

		public function set isTargetsArrayChange(value:Boolean):void
		{
			_isTargetsArrayChange = value;
			needRender = true;
		}

		private var _targetsArray:Array = [];

		public function get targetsArray():Array
		{
			return _targetsArray;
		}

		public function set targetsArray(value:Array):void
		{
			if(!(value is Array))
			{
				value = [];
			}
			_targetsArray = value;
			isTargetsArrayChange = true;
		}

		
		public var seekMode:String = CLOSEST;
		
		private var _text:String = null;
		
		override public function get text():String
		{
			return _text;
		}
		
		override public function set text(value:*):void
		{
			this.value = value;
			isTextChange = true;
		}
		
		private var defaultValue:Object = 
		{
			"backgroundColor" : 0xFFFFFF,
			"seekMode" : CLOSEST
		}
			
		private var _propertiesArray:Array = null;
		
		override public function get propertiesArray():Array
		{
			if(_propertiesArray)
			{
				return _propertiesArray;
			}
			
			_propertiesArray = super.propertiesArray;
			for(var name:String in defaultValue)
			{
				if(!ArrayUtil.containsValue(_propertiesArray, name))
				{
					_propertiesArray.push(name);
				}
			}
			return _propertiesArray;
		}
		
		public function DataTip()
		{
			super();
			
			mouseChildren = false;
			mouseEnabled = false;
		}
		
		override public function getDefaultValue(name:String):*
		{
			return (defaultValue[name] === undefined) ? super.getDefaultValue(name) : defaultValue[name];
		}
		
		override public function update(callAfterUpdate:Boolean=true):Boolean
		{
			if(isTextChange || isTargetsArrayChange)
			{
				isTargetsArrayChange = false;
				if(targetsArray.length > 0)
				{
					if(value == null || value === undefined)
					{
						_text = "";
					}
					else
					{
						try
						{
							var string:String = String(value);
							if(string.indexOf(CODE_VALUE))
							{
								var targetsValue:String = "";
								for each(var target:DataElement in targetsArray)
								{
									if(targetsValue != "")
									{
										targetsValue += " ";
									}
									if(target.value is Number)
									{
										targetsValue += (target.value as Number).toFixed(fractionFix);
									}
									else
									{
										targetsValue += String(target.value);
									}
								}
								string = StringUtil.replace(string, CODE_VALUE, targetsValue);
							}
							_text = string;
						}
						catch(error:Error)
						{
							_text = "";
						}
					}
				}
				else
				{
					_text = "";
				}
			}
			
			if(!super.update(false))
			{
				return false;
			}
			
			if(isPaddingChange)
			{
				isPaddingChange = false;
			}
			
			if(callAfterUpdate)
			{
				return afterUpdate();
			}
			return true;
		}
		
		public function show():void
		{
			visible = true;
			var serializationAlpha:Number = getSerializationValue("alpha");
			if(alpha != serializationAlpha)
			{
				Tweener.addTween(this, {alpha:serializationAlpha, time:0.3});
			}
		}
		
		public function hide():void
		{
			Tweener.addTween(this, {alpha:0, time:0.3, onComplete:setInvisible});
		}
		
		private function setInvisible():void
		{
			visible = false;
		}
	}
}